﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace KulaTools
{
    public class Password
    {
        private static readonly Random Random = new Random();

        /// <summary>
        /// Generate passwords.Strong uses characters.Uses pseudo random generator.
        /// </summary>
        /// <param name="passwordLength"></param>
        /// <param name="strongPassword"> </param>
        /// <returns></returns>
        public static string Generate(int passwordLength, bool strongPassword)
        {
            int seed = Random.Next(1, int.MaxValue);
            //const string allowedChars = "ABCDEFGHJKLMNOPQRSTUVWXYZ0123456789";
            const string allowedChars = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ123456789";
            //const string specialCharacters = @"!#$%&'()*+,-./:;<=>?@[\]_";
            const string specialCharacters = @"!#$%+-=?@[]";

            var chars = new char[passwordLength];
            var rd = new Random(seed);

            for (var i = 0; i < passwordLength; i++)
            {
                // If we are to use special characters
                if (strongPassword && i % Random.Next(3, passwordLength) == 0)
                {
                    chars[i] = specialCharacters[rd.Next(0, specialCharacters.Length)];
                }
                else
                {
                    chars[i] = allowedChars[rd.Next(0, allowedChars.Length)];
                }
            }

            return new string(chars);
        }


        /// <summary>
        /// Checks the complexity of a password based on common sense and knowledge. It is moderate strength.
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        public static string ComplexityCheck(string userName, string password, int minLength = 8)
        {
            string un = userName;
            string pw = password;

            if (password.Length < minLength)
            {
                return String.Format("Password is too short. Please use at least {0} letters", minLength);
            }

            //Account name as password?
            string unLocal = un.Split('@')[0];
            if (pw.Contains(unLocal))
            {
                return "Your password cannot contain your account name.";
            }

            //Any canonical account name included in password?
            string[] unParts = unLocal.Split('.', '-', '_', '!');
            foreach (string unp in unParts)
            {
                if (pw.Contains(unp))
                {
                    return "Your password cannot contain parts of your account name.";
                }

            }

            //Words i found in public dictionaries used for brute force attacks atleast 8 characters and as listed worst passwords on CNN
            //Anything that matches or contains these are a vulnerability threat
            string[] bannedPasswords = new string[] {"swimming","superman","whatever","dolphins","trustno1","access14","mountain","einstein","redwings",
                                                        "jennifer","iloveyou","cocacola","baseball","steelers","firebird","starwars","sunshine","samantha","11111111","xxxxxxxx",
                                                        "computer","bigdaddy","startrek","victoria","password","password1",
                                                        "internet","mercedes","princess","butthead","srinivas","redskins","midnight","nicholas","hardcore","rush2112",
                                                        "corvette","scorpion","football","michelle","mistress","maverick","qwertyui","12345678","danielle","marlboro",
                                                        //well known and shoulb be avioded no matter what
                                                        "ninja","111111","letmein","123456","iloveyou ","trustno1","master","123123","abc","welcome","ashley",
                                                        "qwaszx","qazwsx","qwerty","123","321","111"
                                                        //'jesus' is well known but we cannot ban Jesus!
                                                    };

            //This is fast enough for this small test list.
            foreach (string banned in bannedPasswords)
            {
                if (pw.Contains(banned))
                {
                    return "'" + banned + "' is not allowed to be used within your password.";
                }
            }



            return "";
        }



    }
}
